package com.allen.app.code;

import static cn.hutool.core.lang.Console.log;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.allen.app.AppApplication;
import com.allen.app.common.utils.CheckObjectUtils;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.NullCacheStorage;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;
import org.springframework.util.CollectionUtils;

/**
 * Description: 描述：代码生成器 Created by Ay on 2017/5/1.
 *
 * @author Limiaojun
 * @date 2019/6/28 11:44
 **/
@ToString
public class CodeGenerateService {

    //生成注释配置
    private final String AUTHOR = "Limiaojun";
    private final String CURRENT_DATE = DateUtil.date().toDateStr();
    private final String CURRENT_DATE_TIME = DateUtil.date().toString();


    //实例化数据库: (默认数据库),如需更换修改构造方法
    private DBSetting dbSetting = new DBSetting(
//        "jdbc:mysql://120.77.181.213:3306/test_db?useSSL=false",
//        "root", "root", "com.mysql.jdbc.Driver"
    );

    public static void main(String[] args) throws Exception {
        CodeGenerateService codeGenerateUtils = new CodeGenerateService();
        //默认生成全部 DOMAIN,MAPPERXML,MAPPERJAVA,SERVICE,API
        String ftlTemplates = "";
        codeGenerateUtils.init(ftlTemplates,"example","test_demo",true,"");
        //子工程名称,不是子工程可不用填
        String childerProjectName = "\\app-server\\";
        codeGenerateUtils.generate(childerProjectName);
        //如果有统一前缀记得修改   tableTirmPrefix


        //据表生成java对象 默认lombok插件生成
//        codeGenerateUtils.generatorTableToModel(false);
    }


    /**
     * This is a init.
     * @param ftlTemplates  默认生成所有模板,可指定
     * @param moduleName  模块名称
     * @param tables  字符串数组表名称
     * @param overrideFlag  是否重写,会覆盖本地
     * @param diskPath  默认本工程路径,指定路径(结束符需要加上\) D:\lmj\git-project-fork\0lhiot\minapp-shop\
     * @return void
     * @author Limiaojun
     * @date 2021/4/1 0001 10:50
     */
    public void init(String ftlTemplates,String moduleName,String tables,boolean overrideFlag,String diskPath){
        this.ftlTemplates = ftlTemplates;
        //包名
        this.packageName = AppApplication.class.getPackage().getName();
        //模块名
        this.moduleName = moduleName;
        //要生成项目路径 记得结束符需要加上\\
        this.diskPath = diskPath;
        //是否覆盖已存在文件: (谨慎使用,可能导致自己写的代码找不回)
        this.overrideFlag = overrideFlag;
        // 需要生成的table,逗号分割
        this.tableList = CollUtil.toList(tables.split(","));
        this.pagingQueryDto = packageName + ".common.domain.PageDomain";
        this.pagingResultDto = packageName + ".common.domain.PageResult";
        System.out.println(toString());
    }

    // 生成文件中去掉表前缀
    private String tableTirmPrefix = "app_";
    public String packageName;
    public String moduleName;
    private String diskPath;
    private boolean overrideFlag;
    private List<String> tableList;
    //分页路径
    private String pagingQueryDto;
    private String pagingResultDto;
    private String ftlTemplates;

    //读取代码生成模板路径
    public static final String TEMPLATE_BASEPACKAGE_PATH = "/template";


    /**
     * @return java.sql.Connection
     * @description 获取数据库连接
     * @author Limiaojun
     * @date 2019/1/20 15:30
     */
    public Connection getConnection() throws Exception {
        Connection connection = null;
        Class.forName(dbSetting.getDriver());
        Properties props = new Properties();
        props.setProperty("user", dbSetting.getUser());
        props.setProperty("password", dbSetting.getPassword());
        props.setProperty("remarks", "true"); // 设置可以获取remarks信息
        props.setProperty("useInformationSchema", "true");// 设置可以获取tables
        props.setProperty("characterEncoding", "UTF-8");// 设置编码
        connection = DriverManager.getConnection(dbSetting.getUrl(), props);
        return connection;
    }

    /**
     * @return void
     * @description 生成代码业务逻辑
     * @author Limiaojun
     * @date 2019/1/20 15:30
     */
    public void generate(String childerProjectName) throws Exception {
        if (StrUtil.isBlank(diskPath)) {
            //没有指定路劲取当前项目路径
            String filePath = new File("").getCanonicalPath();
            diskPath = filePath.concat(childerProjectName);
        }

        try {
            //如果是同一文件夹标识,取当前项目路径
            File targetFoder = new File(diskPath);
            if (!targetFoder.exists()) {
                targetFoder.mkdirs();
            }
            Connection connection = getConnection();
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            // 查询表
            ResultSet tableRs = databaseMetaData.getTables(null, "%", null, new String[]{"TABLE"});
            while (tableRs.next()) {
                // 生成Mapper文件
                String tableName = tableRs.getString("TABLE_NAME");
                if (!CollectionUtils.isEmpty(tableList) && !tableList.contains(tableName)) {
                    continue;
                }

                // 首字母大写用于定义类
                String changeTableName = replaceUnderLineAndUpperCase(
                    tableName.replaceFirst(tableTirmPrefix, ""));

                // 首字母小写用于申明变量
                String changeTableNameFistLowCase =
                    replaceUnderLineAndUpperCaseFistLowCase(
                        tableName.replaceFirst(tableTirmPrefix, ""));

                //获取所有需要生成文件的枚举
                FtlTemplateEnum[] values = FtlTemplateEnum.values();
                for (FtlTemplateEnum value : values) {
                    if (CheckObjectUtils.nonNull(ftlTemplates) &&
                        !CheckObjectUtils.containsStr(ftlTemplates, value.toString())){
                        continue;
                    }
                    // 遍历枚举生成文件
                    generateFile(value, tableName,
                        changeTableName,
                        changeTableNameFistLowCase,
                        tableRs.getString("REMARKS"),
                        databaseMetaData
                            .getColumns(null, "%", tableRs.getString("TABLE_NAME"), "%"));
                }

            }

            log(">>>\t{}","执行完毕");

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {

        }
    }

    private void generateFile(FtlTemplateEnum ftlTemplateEnum, String tableName,
        String changeTableName,
        String changeTableNameFistLowCase, String tableAnnotation, ResultSet resultSet)
        throws Exception {

        String tempDiskPath = diskPath;
        String javaPath = "src/main/java/";
        String resourcesPath = "src/main/resources/";
        String packagePath = packageName.replaceAll("\\.", "/").concat("/");

        //是否为 src/mian/java路径
        if (ftlTemplateEnum.isJavaPath()) {
            tempDiskPath += javaPath.concat(packagePath).concat(ftlTemplateEnum.getFolderPath())
                .concat("/");
        } else {
            tempDiskPath += resourcesPath.concat(ftlTemplateEnum.getFolderPath()).concat("/");
        }

        //是否有模块名称
        tempDiskPath =
            !StrUtil.isEmpty(moduleName) ? tempDiskPath.concat("/").concat(moduleName.replaceAll("\\.", "/"))
                .concat("/") : tempDiskPath;

        File targetFoder = new File(tempDiskPath);
        if (!targetFoder.exists()) {
            targetFoder.mkdirs();
        }

        //获取路径
        final String path =
            tempDiskPath + (ftlTemplateEnum.getSuffix().equals("List.ftl")
                ? changeTableNameFistLowCase
                : changeTableName) + ftlTemplateEnum.getSuffix();

        File mapperFile = new File(path);
        List<ColumnClass> columnClassList = new ArrayList<>();
        ColumnClass columnClass = null;

        // 主键和主键类型
        String key = null;
        String keyType = null;
        while (resultSet.next()) {
            // id字段略过
            // if(resultSet.getString("COLUMN_NAME").equals("id")) continue;
            if (null == key) {
                key = resultSet.getString("COLUMN_NAME");
                keyType = colTypeToModType(resultSet.getString("TYPE_NAME"));
            }
            columnClass = new ColumnClass();
            // 获取字段名称
            columnClass.setColumnName(resultSet.getString("COLUMN_NAME"));
            // 获取字段类型
            columnClass.setColumnType(resultSet.getString("TYPE_NAME"));
            // 转换数据库字段类型为model属性类型
            columnClass.setModelAttrType(colTypeToModType(resultSet.getString("TYPE_NAME")));
            // 转换字段名称，如 sys_name 变成 sysName
            columnClass
                .setChangeColumnName(
                    replaceUnderLineAndUpperCaseFistLowCase(resultSet.getString("COLUMN_NAME")));
            // 字段在数据库的注释
            columnClass.setColumnComment(resultSet.getString("REMARKS"));
            //注释为空取字段名
            columnClass.setColumnComment(
                CheckObjectUtils.isNull(columnClass.getColumnComment()) ? columnClass.getChangeColumnName() :
                    columnClass.getColumnComment());
            columnClassList.add(columnClass);
        }
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("modelColumn", columnClassList);
        dataMap.put("primaryKey", key);
        dataMap.put("primaryKeyJava", replaceUnderLineAndUpperCase(key));
        dataMap.put("primaryKeyModtype", keyType);

        generateFileByTemplate(tableName, changeTableName, changeTableNameFistLowCase,
            tableAnnotation, ftlTemplateEnum.getTemplateName(),
            mapperFile, dataMap);
    }

    private void generateFileByTemplate(String tableName, String changeTableName,
        String changeTableNameFistLowCase,
        String tableAnnotation, final String templateName, File file, Map<String, Object> dataMap)
        throws Exception {

        Template template = FreeMarkerTemplateUtils.getTemplate(templateName);
        //文件已存在不覆盖
        if (!overrideFlag && file.exists()) {
            return;
        }
        FileOutputStream fos = new FileOutputStream(file);
        dataMap.put("tableNameSmall", tableName);
        dataMap.put("tableName", changeTableName);
        dataMap.put("tableNameFirstLow", changeTableNameFistLowCase);
        dataMap.put("author", AUTHOR);
        dataMap.put("date", CURRENT_DATE);
        dataMap.put("dateTime", CURRENT_DATE_TIME);
        dataMap.put("packageName", packageName);
        dataMap.put("moduleName", moduleName);
        dataMap.put("pagingQueryDto", pagingQueryDto);
        dataMap.put("pagingResultDto", pagingResultDto);
        //设置其他变量
        setOtherVariable(dataMap);

        //添加 项目访问请求路径 RequestMapping
        dataMap.put("tableRequestPath", tableName.replaceAll("_", "-"));

        if (!StrUtil.isEmpty(tableAnnotation)) {
            // 判断最后字符串是否以表结尾 去掉
            String lastStr = tableAnnotation
                .substring(tableAnnotation.length() - 1, tableAnnotation.length());
            if ("表".equals(lastStr)) {
                tableAnnotation = tableAnnotation.substring(0, tableAnnotation.length() - 1);
            }
            if ("Model.ftl".equals(templateName)) {
                tableAnnotation += "实体类";
            }
        }

        dataMap.put("tableAnnotation", tableAnnotation);
//        dataMap.put("pageFlag", pageFlag);
        Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"), 10240);
        template.process(dataMap, out);
    }

    /**
     * Description: 设置其他变量
     *
     * @return void
     * @param: dataMap
     * @author Limiaojun
     * @date 2019/3/22 15:50
     */
    private void setOtherVariable(Map<String, Object> dataMap) {
        //获取所有需要生成文件的枚举
        for (FtlTemplateEnum value : FtlTemplateEnum.values()) {
            //获取所有需要生成文件的枚举
            if (!StrUtil.isEmpty(value.getPackagePath())) {
                if (StrUtil.isEmpty(moduleName)) {
                    dataMap.put(value.getPackagePath(),
                        packageName.concat(".").concat(value.getFolderPath().replaceAll("/", ".")));
                } else {
                    dataMap.put(value.getPackagePath(),
                        packageName.concat(".").concat(value.getFolderPath().replaceAll("/", "."))
                            .concat(".").concat(moduleName)
                    );
                }
            }

            //java文件后缀
            String suffix = value.getSuffix();
            String templateName = value.getTemplateName();
            templateName = templateName.substring(0, templateName.indexOf("."));

            if ("MapperJava".equals(templateName)) {
                templateName = "Mapper";
            }
            String className = templateName.concat("_classname");
            if (!suffix.startsWith(".")) {
                dataMap.put(className.toUpperCase(),
                    dataMap.get("tableName") +
                        suffix.substring(0, suffix.indexOf(".")));

                dataMap.put(className.toLowerCase(),
                    dataMap.get("tableNameFirstLow") +
                        suffix.substring(0, suffix.indexOf(".")));
            } else {
                dataMap.put(className.toUpperCase(),
                    dataMap.get("tableName"));

                dataMap.put(className.toLowerCase(),
                    dataMap.get("tableNameFirstLow"));
            }
        }
    }

    private String replaceUnderLineAndUpperCase(String str) {
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        int count = sb.indexOf("_");
        while (count != 0) {
            int num = sb.indexOf("_", count);
            count = num + 1;
            if (num != -1) {
                char ss = sb.charAt(count);
                char ia = (char) (ss - 32);
                sb.replace(count, count + 1, ia + "");
            }
        }
        String result = sb.toString().replaceAll("_", "");
        return org.springframework.util.StringUtils.capitalize(result);
    }

    private String replaceUnderLineAndUpperCaseFistLowCase(String str) {
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        int count = sb.indexOf("_");
        while (count != 0) {
            int num = sb.indexOf("_", count);
            count = num + 1;
            if (num != -1) {
                char ss = sb.charAt(count);
                char ia = (char) (ss - 32);
                sb.replace(count, count + 1, ia + "");
            }
        }
        String result = sb.toString().replaceAll("_", "");
        return org.springframework.util.StringUtils.uncapitalize(result);
    }

    /**
     * 数据字段类型转model属性类型
     */
    private String colTypeToModType(String colType) {
        colType = colType.toUpperCase();
        String modelType;
        switch (colType) {
            case "INTEGER":
                modelType = "Integer";
                break;
            case "TINYINT":
                modelType = "Integer";
                break;
            case "BIT":
                modelType = "Integer";
                break;
            case "INT":
                modelType = "Integer";
                break;
            case "BIGINT":
                modelType = "Long";
                break;
            case "VARCHAR":
                modelType = "String";
                break;
            case "CHAR":
                modelType = "String";
                break;
            case "TEXT":
                modelType = "String";
                break;
            case "DECIMAL":
                modelType = "BigDecimal";
                break;
            case "DATETIME":
//                modelType = "Timestamp";
                modelType = "Date";
                break;
            case "TIMESTAMP":
//                modelType = "Timestamp";
                modelType = "Date";
                break;
            case "DOUBLE":
                modelType = "Double";
                break;
            case "FLOAT":
                modelType = "Float";
                break;

            case "TINYINT UNSIGNED":
                modelType = "Integer";
                break;
            case "BIGINT UNSIGNED":
                modelType = "Long";
                break;
            case "JSON":
                modelType = "JSONObject";
                break;
            default:
                modelType = colType;
        }
        return modelType;
    }

    /**
     * Description: 根据表生成java对象
     *
     * @param: lombokFlag  是否lombok插件方式生成
     * @return: void
     * @author Limiaojun
     * @date 2019/5/27 11:43
     */
    public void generatorTableToModel(boolean lombokFlag) throws Exception {
        Connection connection = getConnection();
        DatabaseMetaData databaseMetaData = connection.getMetaData();
        // 查询表
        ResultSet tableRs = databaseMetaData.getTables(null, "%", null, new String[]{"TABLE"});
        while (tableRs.next()) {
            // 生成Mapper文件
            String tableName = tableRs.getString("TABLE_NAME");
            String tableRemark = tableRs.getString("REMARKS");
            if (!CollectionUtils.isEmpty(tableList) && !tableList.contains(tableName)) {
                continue;
            }

            // 首字母大写用于定义类
            String changeTableName = replaceUnderLineAndUpperCase(
                tableName.replaceFirst(tableTirmPrefix, ""));

            StringBuilder sb = new StringBuilder();
            sb.append("/**").append(StringUtils.insertStr("\n"));
            sb.append("* Description: ").append(tableRemark).append(StringUtils.insertStr("\n"));
            sb.append("* @author ").append(AUTHOR).append(StringUtils.insertStr("\n"));
            sb.append("* @date ").append(CURRENT_DATE).append(StringUtils.insertStr("\n"));
            sb.append("*/").append(StringUtils.insertStr("\n"));

            if (lombokFlag) {
                sb.append(StringUtils.insertStr("\n"));
                sb.append("@Data").append(StringUtils.insertStr("\n"));
                sb.append("@ToString").append(StringUtils.insertStr("\n"));
                sb.append("@ApiModel(\"").append(tableRemark).append("\")")
                    .append(StringUtils.insertStr("\n"));
            }
            sb.append("public class ").append(changeTableName).append(" {")
                .append(StringUtils.insertStr("\n"));

            //字段集合
            ResultSet resultSet = databaseMetaData
                .getColumns(null, "%", tableRs.getString("TABLE_NAME"), "%");
            List<Map<String, Object>> resultList = Lists.newArrayList();
            String modelName = null;
            String modelType = null;
            String modelRemarks = null;
            while (resultSet.next()) {
                // 转换数据库字段类型为model属性类型
                modelType = colTypeToModType(resultSet.getString("TYPE_NAME"));
                // 转换字段名称，如 sys_name 变成 sysName
                modelName = replaceUnderLineAndUpperCaseFistLowCase(
                    resultSet.getString("COLUMN_NAME"));
                // 字段在数据库的注释
                modelRemarks = resultSet.getString("REMARKS");
                resultList.add(ImmutableMap.of("modelType", modelType, "modelName",
                    modelName));

                sb.append(StringUtils.insertStr(" ", 4)).append("/**").append(StringUtils.insertStr("\n"));
                sb.append(StringUtils.insertStr(" ", 4)).append("* ").append(modelRemarks)
                    .append(StringUtils.insertStr("\n"));
                sb.append(StringUtils.insertStr(" ", 4)).append("*/").append(StringUtils.insertStr("\n"));
                if (lombokFlag) {
                    sb.append(StringUtils.insertStr(" ", 4)).append("@ApiModelProperty(value = \"")
                        .append(modelRemarks).append("\", ")
                        .append("dataType = \"").append(modelType).append("\")")
                        .append(StringUtils.insertStr("\n"));
                }
                sb.append(StringUtils.insertStr(" ", 4)).append("private ").append(modelType)
                    .append(" ").append(modelName).append(";").append(StringUtils.insertStr("", 2));

            }

            for (Map<String, Object> map : resultList) {
                sb.append(StringUtils.insertStr(" ", 4)).append("public ").append(map.get("modelType"))
                    .append(" get")
                    .append(replaceUnderLineAndUpperCase(String.valueOf(map.get("modelName"))))
                    .append("() {").append(StringUtils.insertStr("\n"));
                sb.append(StringUtils.insertStr(" ", 4)).append(StringUtils.insertStr(" ", 4))
                    .append("return ").append(map.get("modelName")).append(";")
                    .append(StringUtils.insertStr("\n"));
                sb.append(StringUtils.insertStr(" ", 4)).append("}").append(StringUtils.insertStr(" ", 2));

                sb.append(StringUtils.insertStr(" ", 4)).append("public ").append("void")
                    .append(" set")
                    .append(replaceUnderLineAndUpperCase(String.valueOf(map.get("modelName"))))
                    .append("(").append(map.get("modelType")).append(" ")
                    .append(map.get("modelName"))
                    .append(") {").append(StringUtils.insertStr("\n"));
                sb.append(StringUtils.insertStr(" ", 4)).append(StringUtils.insertStr(" ", 4))
                    .append("this.").append(map.get("modelName"))
                    .append(" = ").append(map.get("modelName")).append(";")
                    .append(StringUtils.insertStr("\n"));
                sb.append(StringUtils.insertStr(" ", 4)).append("}").append(StringUtils.insertStr(" ", 2));
            }
            sb.append("}");

            String filePath = new File("").getCanonicalPath();
            if (filePath.contains("code-generator")) {
                filePath = filePath.concat("\\");
            } else {
                filePath = filePath.concat("\\code-generator\\");
            }
            filePath += "\\src\\main\\java\\com\\lean\\demo\\";
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdir();
            }
            file = new File(filePath + changeTableName + ".java");

            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(sb.toString());
            fileWriter.close();

            System.out.println("生成完成,请刷新文件夹");
        }
    }

    @Data
    public static class ColumnClass {

        /**
         * 数据库字段名称
         **/
        private String columnName;
        /**
         * 数据库字段类型
         **/
        private String columnType;
        /**
         * 数据库字段首字母小写且去掉下划线字符串
         **/
        private String changeColumnName;
        /**
         * 数据库字段类型对应model属性类型
         **/
        private String modelAttrType;
        /**
         * 数据库字段注释
         **/
        private String columnComment;
    }

}

/**
 * Description: This is a FreeMarkerTemplateUtils
 *
 * @author Limiaojun
 * @date 2019/5/22 9:16
 **/
class FreeMarkerTemplateUtils {

    private FreeMarkerTemplateUtils() {
    }

    private static final Configuration CONFIGURATION = new Configuration(
        Configuration.VERSION_2_3_22);

    static {
        //这里比较重要，用来指定加载模板所在的路径
        CONFIGURATION.setTemplateLoader(new ClassTemplateLoader(FreeMarkerTemplateUtils.class,
            CodeGenerateService.TEMPLATE_BASEPACKAGE_PATH));
        CONFIGURATION.setDefaultEncoding("UTF-8");
        CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        CONFIGURATION.setCacheStorage(NullCacheStorage.INSTANCE);
        CONFIGURATION.setClassicCompatible(true);
    }

    public static Template getTemplate(String templateName) throws IOException {
        try {
            return CONFIGURATION.getTemplate(templateName);
        } catch (IOException e) {
            throw e;
        }
    }

    public static void clearCache() {
        CONFIGURATION.clearTemplateCache();
    }
}

/**
 * Description: 数据库配置
 *
 * @author Limiaojun
 * @date 2019/5/22 9:24
 **/
@Data
class DBSetting {

    private String url;
    private String user;
    private String password;
    private String driver;

    /**
     * Description: 默认配置
     *
     * @return:
     * @author Limiaojun
     * @date
     */
    public DBSetting() {
        this.driver = "com.mysql.jdbc.Driver";
        this.url = "jdbc:mysql://172.16.10.201:3306/allen_app?useSSL=false";
        this.user = "root";
        this.password = "root";
    }

    public DBSetting(String url, String user, String password) {
        this.url = url;
        this.user = user;
        this.password = password;
    }

    public DBSetting(String url, String user, String password, String driver) {
        this.url = url;
        this.user = user;
        this.password = password;
        this.driver = driver;
    }
}

/**
 * Description: freemarker 模板枚举类
 *
 * @author Limiaojun
 * @date 2019/5/22 9:41
 **/
@AllArgsConstructor
@Getter
enum FtlTemplateEnum {
    DOMAIN(".java", "Domain.ftl", "domain", true, "setDomainPackageName"),
    MAPPERXML("Mapper.xml", "Mapper.ftl", "mappers", false, "setMapperPackageName"),
    MAPPERJAVA("Mapper.java", "MapperJava.ftl", "mapper", true, "setMapperPackageName"),
    SERVICE("Service.java", "Service.ftl", "service", true, "setServicePackageName"),
    API("Controller.java", "Api.ftl", "api", true, "setApiPackageName");
//    SERVICEFEIGN("ServiceFeign.java", "ServiceFeign.ftl", "other", false, "setFeginPackageName"),
//    SERVICEFEIGN_API("Api.java", "ServiceFeignApi.ftl", "other", false, "setFeginPackageName")
    ;

    //生成文件后缀
    private String suffix;
    //模板名称
    private String templateName;
    //生成代码文件夹路径: (支持多级文件夹,如 dao/impl)
    private String folderPath;
    //是否为 src/mian/java路径
    private boolean isJavaPath;
    //设置包路径名称
    private String packagePath;
}

class StringUtils {
    /**
     * 插入多个指定字符,默认一个
     *
     * @return java.lang.String
     * @param: num
     * @author Limiaojun
     * @date 2019/3/18 11:20
     */
    public static String insertStr(String str,int ... num) {
        StringBuilder stb = new StringBuilder();
        if(num.length == 0){
            return stb.append(str).toString();
        }
        for (int i = 0; i < num[0]; i++) {
            stb.append(str);
        }
        return stb.toString();
    }
}